package com.shop.cereshop.commons.tencent.moderation.service.impl;

import com.shop.cereshop.commons.tencent.moderation.cache.ModerationCacheManager;
import com.shop.cereshop.commons.tencent.moderation.config.TencentModerationConfig;
import com.shop.cereshop.commons.tencent.moderation.domain.request.ImageModerationParam;
import com.shop.cereshop.commons.tencent.moderation.domain.response.ModerationResult;
import com.shop.cereshop.commons.tencent.moderation.service.ImageModerationService;
import com.shop.cereshop.commons.tencent.moderation.util.HashUtils;
import com.shop.cereshop.commons.tencent.moderation.util.ImageUtils;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.ims.v20201229.ImsClient;
import com.tencentcloudapi.ims.v20201229.models.ImageModerationRequest;
import com.tencentcloudapi.ims.v20201229.models.ImageModerationResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import java.util.Base64;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @description:
 * @author zdd
 * @date 2025/10/26 15:52
 * @version 1.0
 */
@Slf4j
@Service
public class ImageModerationServiceImpl implements ImageModerationService {

    @Autowired
    private TencentModerationConfig config;

    @Autowired
    private ModerationCacheManager cacheManager;

    @Override
    @Retryable(value = TencentCloudSDKException.class,
            maxAttempts = 3,
            backoff = @Backoff(delay = 1000, multiplier = 2))
    public ModerationResult moderateImage(ImageModerationParam param) {
        long startTime = System.currentTimeMillis();

        try {
            // 参数验证
            if (!param.hasUrl() && !param.hasBase64()) {
                return ModerationResult.fail("必须提供图片URL或Base64编码");
            }

            // 验证URL格式
            if (param.hasUrl()) {
                log.info("图片URL: {}", param.getImageUrl());
                if (!ImageUtils.isValidUrl(param.getImageUrl())) {
                    return ModerationResult.fail("图片URL格式不正确");
                }
            }

            // 检查缓存
            String cacheKey = param.hasUrl() ?
                    HashUtils.md5(param.getImageUrl()) :
                    HashUtils.md5(param.getImageBase64().substring(0, Math.min(100, param.getImageBase64().length())));

            ModerationResult cachedResult = cacheManager.getImageResult(cacheKey);
            if (cachedResult != null) {
                cachedResult.setCostTime(System.currentTimeMillis() - startTime);
                log.info("图片审核缓存命中, 耗时: {}ms", cachedResult.getCostTime());
                return cachedResult;
            }

            // 调用腾讯云API
            ImsClient client = createImsClient();
            ImageModerationRequest imsRequest = new ImageModerationRequest();
            imsRequest.setBizType(StringUtils.isNotBlank(param.getBizType()) ? param.getBizType()
                    : config.getModeration().getImage().getBizType());
            imsRequest.setDataId(StringUtils.isNotBlank(param.getDataId()) ? param.getDataId() : UUID.randomUUID().toString());
            if (param.hasUrl()) {
                // imsRequest.setFileUrl(param.getImageUrl());
                String base64Image = ImageUtils.downloadImageToBase64(param.getImageUrl());
                imsRequest.setFileContent(base64Image);
            } else {
                imsRequest.setFileContent(param.getImageBase64());
            }

            ImageModerationResponse response = client.ImageModeration(imsRequest);
            // log.info("单个图片审核, request: {}, response: {}", JSON.toJSONString(imsRequest), JSON.toJSONString(response));

            ModerationResult result = ModerationResult.success(response.getSuggestion(), response.getLabel(), response.getScore());
            result.setModerationType("IMAGE")
                    .setCostTime(System.currentTimeMillis() - startTime)
                    .setDataId(imsRequest.getDataId())
                    .setBizType(imsRequest.getBizType())
                    .setModerationTime(System.currentTimeMillis());

            // 缓存结果
            cacheManager.putImageResult(cacheKey, result);

            log.info("图片审核完成, suggestion: {}, label: {}, score: {}, 耗时: {}ms",
                    result.getSuggestion(), result.getLabel(), result.getScore(), result.getCostTime());

            return result;

        } catch (TencentCloudSDKException e) {
            log.error("图片审核失败, error: {}", e.getMessage(), e);
            // 如果是参数错误，可能是腾讯云也无法访问该URL
            if ("InvalidParameter".equals(e.getErrorCode())) {
                throw new RuntimeException("图片URL无法访问，请检查URL有效性或使用有效的SSL证书");
            }
            return ModerationResult.fail("图片审核服务异常: " + e.getMessage())
                    .setCostTime(System.currentTimeMillis() - startTime);
        }
    }

    @Override
    public List<ModerationResult> batchModerateImages(List<ImageModerationParam> requests) {
        return requests.parallelStream()
                .map(this::moderateImage)
                .collect(Collectors.toList());
    }

    @Async("moderationExecutor")
    @Override
    public CompletableFuture<ModerationResult> moderateImageAsync(ImageModerationParam request) {
        return CompletableFuture.completedFuture(moderateImage(request));
    }

    private ImsClient createImsClient() {
        Credential cred = new Credential(config.getSecretId(), config.getSecretKey());
        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setEndpoint("ims.tencentcloudapi.com");
        httpProfile.setConnTimeout(config.getModeration().getImage().getTimeout());

        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);

        return new ImsClient(cred, config.getRegion(), clientProfile);
    }

}
